//
//  PersistenceViewController.m
//  iPhoneDev01
//
//  Created by smu on 11-7-12.
//  Copyright 2011年 duk. All rights reserved.
//

/**********
 
 NSManagedObjectContext 书上说这个叫“托管对象上下文”，感觉很别扭，我自己理解，这个东西就相当于获得一个当前程序所拥有的“数据库”
 NSFetchRequest 书上讲这个叫做“请求”，还是比较好理解的（相当于 “select * from”）
 NSEntityDescription 书上叫“实体描述”，其实就相当于选择表 （相当于 "select * from xxx" 中的 xxx 部分）
 NSPredicate 这个我理解为就是一个过滤条件（相当于 "where xxx" 部分）
 
 
 所以一个读取的过程，可以理解为，通过 NSFetchRequest 请求 NSManagedObjectContext 的 NSEntityDescription 中符合 NSPredicate 条件的对象
 */


#import "PersistenceViewController.h"
#import "_1_Core_Data_PersistenceAppDelegate.h"

@implementation PersistenceViewController
@synthesize line1;
@synthesize line2;
@synthesize line3;
@synthesize line4;
- (void)applicationWillTerminate:(NSNotification *)notification
{
    //获取对应用程序委托的引用
    _1_Core_Data_PersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    //使用此引用获取所所创建的托管对象上下文(相当于获得一个当前程序所拥有的“数据库”)
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSError *error;
    
    //使用循环为每个标签执行一次
    for (int i = 1; i <= 4; i++) {
        NSString *fieldName = [NSString stringWithFormat:@"line%d", i];
        UITextField *theField = [self valueForKey:fieldName];
        
        //创建提取请求（相当于 “select * from”）
        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        //数据模型编辑器中设计的Line实体创建一个实体描述,其实就相当于选择表 （相当于 "select * from xxx" 中的 xxx 部分）
        NSEntityDescription *entityDescription = [NSEntityDescription
                                                  entityForName:@"Line" 
                                                  inManagedObjectContext:context];
        //创建实体描述之后，我们需要将它发送给提取请求，以便请求能够知道要查找的实体类型
        [request setEntity:entityDescription];
        //创建实体描述之后，我们需要将它发送给提取请求，以便请求能够知道要查找的实体类型,
        //一个过滤条件（相当于 "where xxx" 部分
        NSPredicate *pred = [NSPredicate predicateWithFormat:@"(lineNum = %d)", i];
        [request setPredicate:pred];
        
        //我们不知道从持久库中加载托管对象，还是创建新的托管对象
        NSManagedObject *theLine = nil;
        
        //在次在上下文中执行提取请求
        NSArray *objects = [context executeFetchRequest:request error:&error];
        
        if (objects == nil) {
            NSLog(@"There was an error!");
        }
        //检查是否返回了与标准相匹配的对象，如果有则加载它，
        //如果没有，则创建一个新的托管对象来保存此字段的文本
        if ([objects count] > 0) {
            theLine = [objects objectAtIndex:0];
        } else {
            theLine = [NSEntityDescription insertNewObjectForEntityForName:@"Line"
                                                    inManagedObjectContext:context];
        }
        //使用键/值编码来设置行号及此托管对象的文本
        [theLine setValue:[NSNumber numberWithInt:i] forKey:@"lineNum"];
        [theLine setValue:theField.text forKey:@"lineText"];
            
        [request release];
    }
    [context save:&error];
}

- (void)viewDidLoad
{
    _1_Core_Data_PersistenceAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    NSManagedObjectContext *context = [appDelegate managedObjectContext];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Line"
                                                         inManagedObjectContext:context];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];
    
    NSError *error;
    NSArray *objects = [context executeFetchRequest:request error:&error];
    if (objects == nil) {
        NSLog(@"There was an error");
    }
    for (NSManagedObject *oneObject in objects) {
        NSNumber *lineNum = [oneObject valueForKey:@"lineNum"];
        NSString *lineText = [oneObject valueForKey:@"lineText"];
        
        NSString *fieldName = [NSString stringWithFormat:@"line%@", lineNum];
        UITextField *theField = [self valueForKey:fieldName];
        theField.text = lineText;
    }
    [request release];
    
    UIApplication *app = [UIApplication sharedApplication];
    [[NSNotificationCenter defaultCenter]  addObserver:self 
                                            selector:@selector(applicationWillTerminate:) 
                                                  name:UIApplicationWillTerminateNotification
                                               object:app];
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)viewDidUnload
{
    self.line1 = nil;
    self.line2 = nil;
    self.line3 = nil;
    self.line4 = nil;
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}
- (void)dealloc
{
    [line1 release];
    [line2 release];
    [line3 release];
    [line4 release];
    [super dealloc];
}


@end
